package com.fas.system.service.impl;

import com.fas.common.constant.Constants;
import com.fas.common.core.domain.entity.SysDictData;
import com.fas.common.core.redis.RedisCache;
import com.fas.system.domain.FasEquipment;
import com.fas.system.domain.FasEquipmentHistoryStatistical;
import com.fas.system.domain.vo.NumberStatistics;
import com.fas.system.domain.vo.StatisticalDetailContentVo;
import com.fas.system.domain.vo.StatisticalDetailVo;
import com.fas.system.mapper.FasEquipmentHistoryStatisticalMapper;
import com.fas.system.mapper.FasEquipmentMapper;
import com.fas.system.mapper.SysDictDataMapper;
import com.fas.system.service.IFasEquipmentHistoryStatisticalService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.time.DayOfWeek;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@Service
public class FasEquipmentHistoryStatisticalServiceImpl implements IFasEquipmentHistoryStatisticalService {

    private final static Logger logger = LoggerFactory.getLogger(FasEquipmentHistoryStatisticalServiceImpl.class);
    SimpleDateFormat datetimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
    SimpleDateFormat monthFormat = new SimpleDateFormat("yyyy-MM");

    @Resource
    private FasEquipmentHistoryStatisticalMapper statisticalMapper;
    @Resource
    private FasEquipmentMapper fasEquipmentMapper;
    @Resource
    private SysDictDataMapper sysDictDataMapper;
    @Resource
    private RedisCache redisCache;

    /**
     * 保存设备历史统计数据
     */
    @Override
    public void saveFasEquipmentHistoryStatistical() {
        // 定时任务是每天零晨12点开始执行，统计的是前一天的数据，所以时间要减一天
        LocalDate date = LocalDate.now();
        LocalDate yesterday = date.plusDays(-1);
        ZoneId zone = ZoneId.systemDefault();
        Instant instant = yesterday.atStartOfDay().atZone(zone).toInstant();
        Date yesterdayDate = Date.from(instant);
        int weekOfYear = this.getWeekOfYear();
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyyMM");
        String batchNumber = df.format(yesterday) + weekOfYear;//批次号

        int month = yesterday.getMonthValue();
        DayOfWeek dayOfWeek = yesterday.getDayOfWeek();
        int week = dayOfWeek.getValue();//星期
        //判断数据库中是否存在该批次数据，如果存在则不执行
        int exists = statisticalMapper.existsBatchNumber(batchNumber, week);
        if (exists > 0) {
            logger.error("据库中已存在该批次数据！！！");
            return;
        }

        List<Integer> companyList = fasEquipmentMapper.selectAllCompany(); //设备表中所有单位的数组
        //所有设备系统分类集合
        List<SysDictData> sysDictDataList = sysDictDataMapper.selectDictDataByType("sys_equipment_system");
        //查询设备总数
        int totalNum = fasEquipmentMapper.countEquipment(new FasEquipment()).intValue();

        List<FasEquipmentHistoryStatistical> statisticalList = new ArrayList<>();
        for (Integer company : companyList) {
            for (SysDictData dictData : sysDictDataList) {
                String dictValue = dictData.getDictValue();
                FasEquipmentHistoryStatistical statistical = new FasEquipmentHistoryStatistical();
                statistical.setBatchNumber(batchNumber);//批次号
                statistical.setWeek(week);
                statistical.setTotalNumber(totalNum);
                statistical.setSystemId(dictValue);
                statistical.setCooperationCompanyId(company);
                statistical.setStatisticalDate(yesterdayDate);
                statistical.setWeekOfYear(weekOfYear);
                statistical.setMonthOfYear(month);
                // 设备状态的数量
                List<NumberStatistics> numberStatistics = fasEquipmentMapper.statisticalBySystemId(dictValue, company);
                // 统计设备的各个状态的数量
                for (NumberStatistics equipmentStatusList : numberStatistics) {
                    Integer count = equipmentStatusList.getCount();
                    Integer status = equipmentStatusList.getStatus();
                    if (status != null) {
                        if (status == Constants.DEVICE_TYPE_FAULT) {
                            statistical.setFaultNumber(count);
                        } else if (status == Constants.DEVICE_TYPE_OFF_LINE) {
                            statistical.setOfflineNumber(count);
                        } else if (status == Constants.DEVICE_TYPE_ALARM) {
                            statistical.setAlarmNumber(count);
                        }
                    }
                }
                statisticalList.add(statistical);
            }
        }
        statisticalMapper.insertStatistical(statisticalList);
    }

    @Override
    public List<FasEquipmentHistoryStatistical> listStatisticsData(FasEquipmentHistoryStatistical fasEquipmentHistoryStatistical) {
        SimpleDateFormat yearFormat = new SimpleDateFormat("yyyy");
        List<FasEquipmentHistoryStatistical> list = new ArrayList<>();
        // 1周  2月 3年
        switch (fasEquipmentHistoryStatistical.getType()) {
            case 1:
                list = statisticalMapper.selectWeek(fasEquipmentHistoryStatistical);
                list.forEach(ll -> {
                    ll.setCompanyName(FasCooperationCompanyServiceImpl.COMPANY_NAMES.get(ll.getCooperationCompanyId()));
                    ll.setName(ll.getCompanyName() + dateFormat.format(ll.getUpdateDate()));
                });
                break;
            case 2:
                list = statisticalMapper.selectMonth(fasEquipmentHistoryStatistical);
                list.forEach(ll -> {
                    ll.setCompanyName(FasCooperationCompanyServiceImpl.COMPANY_NAMES.get(ll.getCooperationCompanyId()));
                    ll.setName(ll.getCompanyName() + dateFormat.format(ll.getUpdateDate()));
                });
                break;
            case 3:
                list = statisticalMapper.selectYear(fasEquipmentHistoryStatistical);
                list.forEach(ll -> {
                    ll.setCompanyName(FasCooperationCompanyServiceImpl.COMPANY_NAMES.get(ll.getCooperationCompanyId()));
                    ll.setName(ll.getCompanyName() + yearFormat.format(ll.getUpdateDate()));
                });
                break;
        }
        return list;
    }

    @Override
    public StatisticalDetailContentVo getStatisticsDetail(FasEquipmentHistoryStatistical fasEquipmentHistoryStatistical) {
        StatisticalDetailContentVo statisticalDetailContentVo = new StatisticalDetailContentVo();
        List<StatisticalDetailVo> statisticalDetailVoList = new ArrayList<>();
        Integer type = fasEquipmentHistoryStatistical.getType();
        List<SysDictData> sysDictDataList = sysDictDataMapper.selectDictDataByType("sys_equipment_system");

        String startTime = "";
        String endTime = "";
        Date createDate = null;
        Integer total = null;
        int alarmNumber = 0;//报警数量
        int faultNumber = 0;//故障数量
        int offlineNumber = 0;//离线数量
        // 1周  2月 3年
        switch (type) {
            case 1:  //参数： cooperationCompanyId
                for (SysDictData dictData : sysDictDataList) {
                    String systemId = dictData.getDictValue();
                    fasEquipmentHistoryStatistical.setSystemId(systemId);
                    List<FasEquipmentHistoryStatistical> statisticalList = statisticalMapper.selectWeekDetail(fasEquipmentHistoryStatistical);
                    statisticalDetailVoList.add(getWeekEquipmentStatus(statisticalList, systemId, type));
                    startTime = dateFormat.format(statisticalList.get(0).getStatisticalDate());
                    endTime = dateFormat.format(statisticalList.get(statisticalList.size()-1).getStatisticalDate());
                    createDate = statisticalList.get(0).getUpdateDate();
                    total = statisticalList.get(statisticalList.size()-1).getTotalNumber();
                    alarmNumber = statisticalList.stream().mapToInt(FasEquipmentHistoryStatistical::getAlarmNumber).sum();
                    faultNumber = statisticalList.stream().mapToInt(FasEquipmentHistoryStatistical::getFaultNumber).sum();
                    offlineNumber = statisticalList.stream().mapToInt(FasEquipmentHistoryStatistical::getOfflineNumber).sum();
                }
                break;
            case 2:  // 参数：batchNumber,cooperationCompanyId
                for (SysDictData dictData : sysDictDataList) {
                    String systemId = dictData.getDictValue();
                    fasEquipmentHistoryStatistical.setSystemId(systemId);
                    List<FasEquipmentHistoryStatistical> statisticalList = statisticalMapper.selectMonthDetail(fasEquipmentHistoryStatistical);
                    statisticalDetailVoList.add(getWeekEquipmentStatus(statisticalList, systemId, type));
                    startTime = dateFormat.format(statisticalList.get(0).getStatisticalDate());
                    endTime = dateFormat.format(statisticalList.get(statisticalList.size()-1).getStatisticalDate());
                    createDate = statisticalList.get(0).getUpdateDate();
                    total = statisticalList.get(statisticalList.size()-1).getTotalNumber();
                    alarmNumber = statisticalList.stream().mapToInt(FasEquipmentHistoryStatistical::getAlarmNumber).sum();
                    faultNumber = statisticalList.stream().mapToInt(FasEquipmentHistoryStatistical::getFaultNumber).sum();
                    offlineNumber = statisticalList.stream().mapToInt(FasEquipmentHistoryStatistical::getOfflineNumber).sum();
                }
                break;
            case 3:// 参数：updateDate,cooperationCompanyId
                for (SysDictData dictData : sysDictDataList) {
                    String systemId = dictData.getDictValue();
                    fasEquipmentHistoryStatistical.setSystemId(systemId);
                    List<FasEquipmentHistoryStatistical> statisticalList = statisticalMapper.selectYearDetail(fasEquipmentHistoryStatistical);
//                    if (statisticalList.size() < 1) break;
//                    else
                    statisticalDetailVoList.add(getWeekEquipmentStatus(statisticalList, systemId, type));
                    startTime = dateFormat.format(statisticalList.get(0).getStatisticalDate());
                    endTime = dateFormat.format(statisticalList.get(statisticalList.size()-1).getStatisticalDate());
                    total = statisticalList.get(statisticalList.size()-1).getTotalNumber();
                    alarmNumber = statisticalList.stream().mapToInt(FasEquipmentHistoryStatistical::getAlarmNumber).sum();
                    faultNumber = statisticalList.stream().mapToInt(FasEquipmentHistoryStatistical::getFaultNumber).sum();
                    offlineNumber = statisticalList.stream().mapToInt(FasEquipmentHistoryStatistical::getOfflineNumber).sum();
                }
                createDate = statisticalMapper.selectUpdateByDate(fasEquipmentHistoryStatistical);
                break;
        }
        statisticalDetailContentVo.setStatisticalDetailVoList(statisticalDetailVoList);
        statisticalDetailContentVo.setBeginTime(startTime);
        statisticalDetailContentVo.setEndTime(endTime);
        statisticalDetailContentVo.setCreateTime(createDate);
        statisticalDetailContentVo.setTotal(total);
        statisticalDetailContentVo.setAlarmNumber(alarmNumber);
        statisticalDetailContentVo.setFaultNumber(faultNumber);
        statisticalDetailContentVo.setOfflineNumber(offlineNumber);

        return statisticalDetailContentVo;
    }

    private int getWeekOfYear() {
        Calendar calendar = Calendar.getInstance();
        calendar.setFirstDayOfWeek(Calendar.MONDAY);//设置星期一为一周开始的第一天
//        calendar.setMinimalDaysInFirstWeek(4);//可以不用设置
        calendar.setTimeInMillis(System.currentTimeMillis());//获得当前的时间戳
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        return calendar.get(Calendar.WEEK_OF_YEAR);//获得当前日期属于今年的第几周
    }

    private StatisticalDetailVo getWeekEquipmentStatus(List<FasEquipmentHistoryStatistical> list, String systemId, Integer type) {

        List<Integer> alarmNumberList = new ArrayList<>(list.size()); //报警数量数组
        List<Integer> faultNumberList = new ArrayList<>(list.size());// 故障数量数组
        List<Integer> offlineNumberList = new ArrayList<>(list.size());// 离线数量数组
        List<String> statisticsTimeList = new ArrayList<>(list.size());//统计数组

        for (FasEquipmentHistoryStatistical statistical : list) {
            alarmNumberList.add(statistical.getAlarmNumber());
            faultNumberList.add(statistical.getFaultNumber());
            offlineNumberList.add(statistical.getOfflineNumber());
            Date statisticalDate = statistical.getStatisticalDate();
            if (type == 3)
                statisticsTimeList.add(monthFormat.format(statisticalDate));
            else
                statisticsTimeList.add(dateFormat.format(statisticalDate));
        }
        return new StatisticalDetailVo(systemId, alarmNumberList, faultNumberList, offlineNumberList, statisticsTimeList);
    }


}
